package net.ibizsys.paas.appmodel;

import java.util.HashMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.ibizsys.paas.control.ControlTypes;
import net.ibizsys.paas.controller.IViewController;
import net.ibizsys.paas.core.ModelBaseImpl;
import net.ibizsys.paas.ctrlhandler.ICtrlHandler;
import net.ibizsys.paas.ctrlhandler.ICtrlRender;
import net.ibizsys.paas.ctrlmodel.AppMenuModelGlobal;
import net.ibizsys.paas.ctrlmodel.IAppMenuModel;
import net.ibizsys.paas.security.RemoteLoginGlobal;
import net.ibizsys.paas.util.ObjectHelper;
import net.ibizsys.paas.util.StringHelper;
import net.ibizsys.paas.web.AjaxActionResult;
import net.ibizsys.paas.web.IWebContext;
import net.ibizsys.paas.web.Page;
import net.ibizsys.paas.web.WebConfig;
import net.ibizsys.paas.web.WebContext;
import net.ibizsys.psrt.srv.common.entity.LoginLog;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 应用程序模型
 * @author lionlau
 */
public abstract class AppModelBase extends ModelBaseImpl implements IApplicationModel
{
	private static final Log log = LogFactory.getLog(AppModelBase.class);

	/**
	 * 部件绘制器Map
	 */
	private HashMap<String, ICtrlRender> ctrlRenderMap = new HashMap<String, ICtrlRender>();

	/**
	 * 应用技术
	 */
	protected String strPFType = null;

	/**
	 * 功能页面路径Map
	 */
	private HashMap<String, String> utilPageUrlMap = new HashMap<String, String>();
	
	/**
	 * 应用视图Map
	 */
	private HashMap<String, IAppViewModel> appViewMap = new HashMap<String, IAppViewModel>();
	
	
	/**
	 * 实体应用视图Map
	 */
	private HashMap<String, IAppDEViewModel> appDEViewMap = new HashMap<String, IAppDEViewModel>();
	
	
	/**
	 * 用户菜单模式Map
	 */
	private HashMap<String, String> userModeMenuMap = new HashMap<String, String>();
	
	/**
	 * 应用框架辅助对象
	 */
	private IAppPFHelper iAppModeHelper = null;
	

	public AppModelBase()
	{

	}

	/**
	 * 设置应用标识
	 * @param strId
	 * 
	 */
	protected void setId(String strId)
	{
		this.strId = strId;
	}

	/**
	 * 设置应用名称
	 * @param strName
	 *   the strName to set
	 */
	protected void setName(String strName)
	{
		this.strName = strName;
	}


	/* (non-Javadoc)
	 * @see net.ibizsys.paas.appmodel.IApplicationModel#doFilter(net.ibizsys.paas.controller.IViewController, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
	 */
	@Override
	public boolean doFilter(IViewController iViewController, HttpServletRequest request, HttpServletResponse response) throws Exception
	{
		return false;
	}

	
	
	
	/* (non-Javadoc)
	 * @see net.ibizsys.paas.appmodel.IApplicationModel#doFilter(net.ibizsys.paas.web.Page, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
	 */
	@Override
	public boolean doFilter(Page page, HttpServletRequest request, HttpServletResponse response) throws Exception {
		return false;
	}

	/*
	 * (non-Javadoc)
	 * @see net.ibizsys.paas.core.IApplication#getPFType()
	 */
	@Override
	public String getPFType()
	{
		return this.strPFType;
	}

	/**
	 * 设置应用技术
	 * @param strPFType
	 */
	protected void setPFType(String strPFType)
	{
		this.strPFType = strPFType;

		this.registerUtilPageUrl(UTILPAGE_DOWNLOADTMPFILE, "/ibizutil/exportfile3.jsp?");
		this.registerUtilPageUrl(UTILPAGE_LOGIN, "/ibizutil/login.jsp?");
		this.registerUtilPageUrl(UTILPAGE_LOGOUT, "/ibizutil/logout.jsp?");
		this.registerUtilPageUrl(UTILPAGE_INTERNALERROR, "/ibizutil/showerror.jsp?");
		this.registerUtilPageUrl(UTILPAGE_ACCESSDENY, "/ibizutil/accessdeny.jsp?");

		// 根据技术类型，注册默认绘制器
		if (StringHelper.compare(this.strPFType, PF_JQUERY, true) == 0)
		{
			try
			{
				iAppModeHelper =  (IAppPFHelper) ObjectHelper.create("net.ibizsys.paas.appmodel.jquery.JQAppPFHelper");
				iAppModeHelper.init(this);
				this.registerCtrlRender(ControlTypes.DRBar, "JSTREE", (ICtrlRender) ObjectHelper.create("net.ibizsys.paas.web.jquery.render.DRBarJSTreeRender"));
				this.registerCtrlRender(ControlTypes.ExpBar, "JSTREE", (ICtrlRender) ObjectHelper.create("net.ibizsys.paas.web.jquery.render.ExpBarJSTreeRender"));
				this.registerCtrlRender(ControlTypes.TreeExpBar, "JSTREE", (ICtrlRender) ObjectHelper.create("net.ibizsys.paas.web.jquery.render.ExpBarJSTreeRender"));
				this.registerCtrlRender(ControlTypes.WFExpBar, "JSTREE", (ICtrlRender) ObjectHelper.create("net.ibizsys.paas.web.jquery.render.WFExpBarJSTreeRender"));
				this.registerCtrlRender(ControlTypes.TreeView, "JSTREE", (ICtrlRender) ObjectHelper.create("net.ibizsys.paas.web.jquery.render.TreeJSTreeRender"));
				this.registerCtrlRender(ControlTypes.Grid, "BOOTSTRAPTABLE", (ICtrlRender) ObjectHelper.create("net.ibizsys.paas.web.jquery.render.GridBootstrapTableRender"));
				this.registerCtrlRender(ControlTypes.Grid, "JQUERYDATATABLES", (ICtrlRender) ObjectHelper.create("net.ibizsys.paas.web.jquery.render.GridJQueryDatatableRender"));
				this.registerCtrlRender(ControlTypes.Chart, "ECHARTS3", (ICtrlRender) ObjectHelper.create("net.ibizsys.paas.web.jquery.render.ChartEcharts3Render"));
			}
			catch (Exception ex)
			{
				log.error(ex);
			}
			return;
		}

		if (StringHelper.compare(this.strPFType, PF_EXTJS5, true) == 0)
		{
			try
			{
				iAppModeHelper =  (IAppPFHelper) ObjectHelper.create("net.ibizsys.paas.appmodel.extjs.ExtJSAppPFHelper");
				iAppModeHelper.init(this);
				
				this.registerCtrlRender(ControlTypes.Chart, "ECHARTS3", (ICtrlRender) ObjectHelper.create("net.ibizsys.paas.web.extjs.render.ChartEcharts3Render"));
			}
			catch (Exception ex)
			{
				log.error(ex);
			}
			return;
		}
		
		if (StringHelper.compare(this.strPFType, PF_ANGULARJS, true) == 0)
		{
			try
			{
				iAppModeHelper =  (IAppPFHelper) ObjectHelper.create("net.ibizsys.paas.appmodel.angularjs.NGAppPFHelper");
				iAppModeHelper.init(this);
				
				this.registerCtrlRender(ControlTypes.Chart, "ECHARTS3", (ICtrlRender) ObjectHelper.create("net.ibizsys.paas.web.jquery.render.ChartEcharts3Render"));
			}
			catch (Exception ex)
			{
				log.error(ex);
			}
			return;
		}
	}

	/**
	 * 建立HTTP访问上下文对象
	 * @param iViewController 视图控制器对象 
	 * @param request 
	 * @param response
	 * @return Web访问上下文对象
	 * @throws Exception
	 */
	@Override
	public IWebContext createWebContext(IViewController iViewController, HttpServletRequest request, HttpServletResponse response) throws Exception
	{
		if (StringHelper.isNullOrEmpty(WebConfig.getCurrent().getWebContextObj()))
		{
			IWebContext iWebContext = new WebContext();
			iWebContext.init(request, response, request.getSession().getServletContext());
			doRemoteLogin(iWebContext);
			return iWebContext;
		}
		else
		{
			IWebContext iWebContext = (IWebContext) ObjectHelper.create(WebConfig.getCurrent().getWebContextObj());
			iWebContext.init(request, response, request.getSession().getServletContext());
			doRemoteLogin(iWebContext);
			return iWebContext;
		}
	}
	
	/**
	 * 执行远程登录处理
	 * @param iWebContext
	 * @throws Exception
	 */
	protected void doRemoteLogin(IWebContext iWebContext) throws Exception
	{
		if(!StringHelper.isNullOrEmpty(iWebContext.getCurUserId()))
			return;
		
		String strLoginKey = WebContext.getLoginKey(iWebContext);
		if(StringHelper.isNullOrEmpty(strLoginKey))
		{
			return;
		}
		
		LoginLog loginLog = RemoteLoginGlobal.getLoginLog(strLoginKey);
		if(loginLog == null)
		{
			return;
		}
		
		iWebContext.remoteLogin(loginLog);
	}

	
	/* (non-Javadoc)
	 * @see net.ibizsys.paas.appmodel.IApplicationModel#doViewCtrlAjaxAction(net.ibizsys.paas.controller.IViewController, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.String, java.lang.String, net.ibizsys.paas.ctrlhandler.ICtrlHandler)
	 */
	@Override
	public  AjaxActionResult doViewCtrlAjaxAction(IViewController iViewController,HttpServletRequest request,HttpServletResponse response,String strCtrlId,String strAction,ICtrlHandler iCtrlHandler) throws Exception
	{
		return iCtrlHandler.processAction(strAction,iViewController.getWebContext());
	}
	
	
	
	/* (non-Javadoc)
	 * @see net.ibizsys.paas.appmodel.IApplicationModel#doFilterViewAction(net.ibizsys.paas.controller.IViewController, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.String, net.ibizsys.paas.web.AjaxActionResult)
	 */
	@Override
	public AjaxActionResult doFilterViewAction(IViewController iViewController, HttpServletRequest request, HttpServletResponse response, String strAction, AjaxActionResult ajaxActionResult)
			throws Exception
	{
		return ajaxActionResult;
	}

	/**
	 * 注册控件绘制器
	 * @param strCtrlType 控件类型
	 * @param strRender   绘制器类型 
	 * @param iCtrlRender 绘制器接口
	 * @throws Exception
	 */
	protected void registerCtrlRender(String strCtrlType, String strRender, ICtrlRender iCtrlRender) throws Exception
	{
		String strKey = StringHelper.format("%1$s|%2$s", strCtrlType, strRender);
		this.ctrlRenderMap.put(strKey, iCtrlRender);
	}

	
	/**
	 * 注册应用功能页面路径
	 * @param strUtilPage 功能页面类型
	 * @param strPageUrl  功能页面路径
	 */
	protected void registerUtilPageUrl(String strUtilPage, String strPageUrl)
	{
		utilPageUrlMap.put(strUtilPage, strPageUrl);
	}

	
	/**
	 * 注销控件绘制器
	 * @param strCtrlType
	 * @param strRender
	 * @param iCtrlRender
	 * @throws Exception
	 */
	protected void unRegisterCtrlRender(String strCtrlType, String strRender, ICtrlRender iCtrlRender) throws Exception
	{
		String strKey = StringHelper.format("%1$s|%2$s", strCtrlType, strRender);
		this.ctrlRenderMap.remove(strKey);
	}

	
	/* (non-Javadoc)
	 * @see net.ibizsys.paas.appmodel.IApplicationModel#getCtrlRender(java.lang.String, java.lang.String)
	 */
	@Override
	public ICtrlRender getCtrlRender(String strCtrlType, String strRender)
	{
		String strKey = StringHelper.format("%1$s|%2$s", strCtrlType, strRender);
		return ctrlRenderMap.get(strKey);
	}

	
	/* (non-Javadoc)
	 * @see net.ibizsys.paas.appmodel.IApplicationModel#getUtilPageUrl(java.lang.String)
	 */
	@Override
	public String getUtilPageUrl(String strUtilType) throws Exception
	{
		return utilPageUrlMap.get(strUtilType);
	}

	
	/* (non-Javadoc)
	 * @see net.ibizsys.paas.appmodel.IApplicationModel#installRTDatas()
	 */
	@Override
	public void installRTDatas() throws Exception
	{
		onInstallRTDatas();
	}

	/**
	 * 安装运行时数据
	 * @throws Exception
	 */
	protected void onInstallRTDatas() throws Exception
	{

	}
	
	
	/**
	 * 注册应用视图
	 * @param iAppViewModel
	 * @throws Exception
	 */
	@Override
	public void registerAppView(IAppViewModel iAppViewModel)throws Exception
	{
		appViewMap.put(iAppViewModel.getId(),iAppViewModel);
		if(iAppViewModel instanceof IAppDEViewModel)
		{
			IAppDEViewModel iAppDEViewModel = (IAppDEViewModel)iAppViewModel;
			if(!StringHelper.isNullOrEmpty(iAppDEViewModel.getDEViewId()))
			{
				appDEViewMap.put(iAppDEViewModel.getDEViewId(),iAppDEViewModel);
			}
		}
	}
	
	
	/**
	 * 获取应用视图
	 * @param strAppViewId
	 * @param bTryMode 是否尝试获取
	 * @return
	 * @throws Exception
	 */
	@Override
	public IAppViewModel getAppView(String strAppViewId,boolean bTryMode)throws Exception
	{
		IAppViewModel iAppViewModel = appViewMap.get(strAppViewId);
		if(iAppViewModel == null&& !bTryMode)
		{
			throw new Exception(StringHelper.format("无法获取指定应用视图[%1$s]",strAppViewId));
		}
		return iAppViewModel;
	}
	
	
	
	
	/**
	 * 获取应用实体视图
	 * @param strDEViewId 实体视图标识
	 * @param bTryMode 尝试模式
	 * @return
	 * @throws Exception
	 */
	@Override
	public IAppDEViewModel getAppViewByDEViewId(String strDEViewId,boolean bTryMode)throws Exception
	{
		IAppDEViewModel iAppDEViewModel = appDEViewMap.get(strDEViewId);
		if(iAppDEViewModel == null&& !bTryMode)
		{
			throw new Exception(StringHelper.format("无法获取指定应用实体视图[%1$s]",strDEViewId));
		}
		return iAppDEViewModel;
	}

	/* (non-Javadoc)
	 * @see net.ibizsys.paas.appmodel.IApplicationModel#getAppModelHelper()
	 */
	@Override
	public IAppPFHelper getAppPFHelper()
	{
		return iAppModeHelper;
	}

	/* (non-Javadoc)
	 * @see net.ibizsys.paas.appmodel.IApplicationModel#getAppMenuModel(java.lang.String)
	 */
	@Override
	public IAppMenuModel getAppMenuModel(String strUserMode) throws Exception {
		if(strUserMode == null)
			strUserMode = "";
		String strAppMenuModelId = this.userModeMenuMap.get(strUserMode);
		if(StringHelper.isNullOrEmpty(strAppMenuModelId)){
			strAppMenuModelId = this.userModeMenuMap.get("");
			if(StringHelper.isNullOrEmpty(strAppMenuModelId)){
				throw new Exception(StringHelper.format("无法获取指定用户模式应用菜单模型"));
			}
		}
		return AppMenuModelGlobal.getAppMenuModel(strAppMenuModelId);
	}

	/* (non-Javadoc)
	 * @see net.ibizsys.paas.appmodel.IApplicationModel#registerUserModeMenu(java.lang.String, java.lang.String)
	 */
	@Override
	public void registerUserModeMenu(String strUserMode, String strAppMenuModelId) throws Exception {
		this.userModeMenuMap.put(strUserMode, strAppMenuModelId);
	}
	
	
	/**
     * 准备应用视图
     * @throws Exception
     */
    protected void prepareAppViews()throws Exception {};
}
